<template>
  <view class="container">
    <view class="page-title">原生绘制图表示例</view>

    <!-- 折线图 -->
    <view class="chart-card">
      <view class="chart-title">折线图</view>
      <canvas type="2d" canvas-id="lineChart" class="chart-canvas" @ready="onLineChartReady"></canvas>
    </view>

    <!-- 柱状图 -->
    <view class="chart-card">
      <view class="chart-title">柱状图</view>
      <canvas type="2d" canvas-id="barChart" class="chart-canvas" @ready="onBarChartReady"></canvas>
    </view>

    <!-- 饼图 -->
    <view class="chart-card">
      <view class="chart-title">饼图</view>
      <canvas type="2d" canvas-id="pieChart" class="chart-canvas" @ready="onPieChartReady"></canvas>
    </view>
  </view>
</template>

<script setup>
  import {
    onMounted,
    ref
  } from 'vue';
  import {
    createCanvasContext
  } from '@dcloudio/uni-app';

  // 折线图数据
  const lineData = {
    labels: ['1月', '2月', '3月', '4月', '5月', '6月'],
    datasets: [{
        label: '销量',
        data: [120, 190, 130, 150, 200, 180],
        color: '#3498db'
      },
      {
        label: '利润',
        data: [80, 120, 90, 100, 150, 130],
        color: '#e74c3c'
      }
    ]
  };

  // 柱状图数据
  const barData = {
    labels: ['产品A', '产品B', '产品C', '产品D', '产品E'],
    datasets: [{
        label: '2022',
        data: [120, 190, 130, 150, 200],
        color: '#2ecc71'
      },
      {
        label: '2023',
        data: [150, 220, 140, 180, 240],
        color: '#f39c12'
      }
    ]
  };

  // 饼图数据
  const pieData = {
    labels: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'],
    data: [335, 310, 234, 135, 1548],
    colors: ['#3498db', '#e74c3c', '#2ecc71', '#f39c12', '#9b59b6']
  };

  // 绘制折线图
  const onLineChartReady = (e) => {
    const ctx = createCanvasContext('lineChart', this);
    const {
      width,
      height
    } = e.detail;

    // 清除画布
    ctx.clearRect(0, 0, width, height);

    // 定义边距
    const margin = {
      top: 30,
      right: 30,
      bottom: 40,
      left: 50
    };
    const chartWidth = width - margin.left - margin.right;
    const chartHeight = height - margin.top - margin.bottom;

    // 绘制坐标轴
    drawAxis(ctx, margin, chartWidth, chartHeight);

    // 计算比例尺
    const xScale = chartWidth / (lineData.labels.length - 1);
    const maxValue = Math.max(...lineData.datasets.flatMap(ds => ds.data));
    const yScale = chartHeight / maxValue;

    // 绘制网格线
    drawGridLines(ctx, margin, chartWidth, chartHeight, lineData.labels.length, 5);

    // 绘制数据系列
    lineData.datasets.forEach((dataset, index) => {
      drawLineSeries(ctx, margin, dataset, xScale, yScale, chartHeight);
    });

    // 绘制图例
    drawLegend(ctx, margin, lineData.datasets, width);

    // 绘制完成
    ctx.draw();
  };

  // 绘制柱状图
  const onBarChartReady = (e) => {
    const ctx = createCanvasContext('barChart', this);
    const {
      width,
      height
    } = e.detail;

    // 清除画布
    ctx.clearRect(0, 0, width, height);

    // 定义边距
    const margin = {
      top: 30,
      right: 30,
      bottom: 40,
      left: 50
    };
    const chartWidth = width - margin.left - margin.right;
    const chartHeight = height - margin.top - margin.bottom;

    // 绘制坐标轴
    drawAxis(ctx, margin, chartWidth, chartHeight, barData.labels);

    // 计算比例尺
    const barGroupWidth = chartWidth / barData.labels.length;
    const barWidth = barGroupWidth * 0.4 / barData.datasets.length;
    const maxValue = Math.max(...barData.datasets.flatMap(ds => ds.data));
    const yScale = chartHeight / maxValue;

    // 绘制网格线
    drawGridLines(ctx, margin, chartWidth, chartHeight, barData.labels.length, 5);

    // 绘制数据系列
    barData.datasets.forEach((dataset, dsIndex) => {
      dataset.data.forEach((value, index) => {
        const x = margin.left + index * barGroupWidth + barGroupWidth * 0.3 + dsIndex * barWidth * 1.2;
        const barHeight = value * yScale;
        const y = margin.top + chartHeight - barHeight;

        // 绘制柱子
        ctx.setFillStyle(dataset.color);
        ctx.fillRect(x, y, barWidth, barHeight);

        // 绘制数值
        ctx.setFillStyle('#333');
        ctx.setFontSize(12);
        ctx.fillText(value, x + barWidth / 2 - 8, y - 10);
      });
    });

    // 绘制图例
    drawLegend(ctx, margin, barData.datasets, width);

    // 绘制完成
    ctx.draw();
  };

  // 绘制饼图
  const onPieChartReady = (e) => {
    const ctx = createCanvasContext('pieChart', this);
    const {
      width,
      height
    } = e.detail;

    // 清除画布
    ctx.clearRect(0, 0, width, height);

    // 计算总和
    const total = pieData.data.reduce((sum, value) => sum + value, 0);

    // 计算饼图位置和大小
    const centerX = width / 2;
    const centerY = height / 2 - 20;
    const radius = Math.min(width, height) * 0.3;

    // 绘制饼图
    let startAngle = 0;
    pieData.data.forEach((value, index) => {
      const percentage = value / total;
      const endAngle = startAngle + percentage * Math.PI * 2;

      // 绘制扇形
      ctx.beginPath();
      ctx.setFillStyle(pieData.colors[index]);
      ctx.moveTo(centerX, centerY);
      ctx.arc(centerX, centerY, radius, startAngle, endAngle);
      ctx.closePath();
      ctx.fill();

      // 绘制扇形分隔线
      ctx.beginPath();
      ctx.setStrokeStyle('#fff');
      ctx.setLineWidth(2);
      ctx.moveTo(centerX, centerY);
      ctx.lineTo(
        centerX + radius * Math.cos(startAngle),
        centerY + radius * Math.sin(startAngle)
      );
      ctx.stroke();

      startAngle = endAngle;
    });

    // 绘制图例
    const legendStartY = centerY + radius + 30;
    pieData.labels.forEach((label, index) => {
      const y = legendStartY + index * 25;

      // 图例颜色块
      ctx.setFillStyle(pieData.colors[index]);
      ctx.fillRect(width * 0.25, y, 15, 15);

      // 图例文本
      ctx.setFillStyle('#333');
      ctx.setFontSize(14);
      ctx.fillText(
        `${label}: ${pieData.data[index]} (${((pieData.data[index]/total)*100).toFixed(1)}%)`,
        width * 0.25 + 25,
        y + 12
      );
    });

    // 绘制完成
    ctx.draw();
  };

  // 绘制坐标轴
  function drawAxis(ctx, margin, width, height, labels = []) {
    // X轴
    ctx.beginPath();
    ctx.setStrokeStyle('#ccc');
    ctx.setLineWidth(1);
    ctx.moveTo(margin.left, margin.top);
    ctx.lineTo(margin.left, margin.top + height);
    ctx.lineTo(margin.left + width, margin.top + height);
    ctx.stroke();

    // X轴标签
    if (labels.length) {
      labels.forEach((label, index) => {
        const x = margin.left + (width / (labels.length - 1)) * index;
        ctx.setFillStyle('#666');
        ctx.setFontSize(12);
        ctx.setTextAlign('center');
        ctx.fillText(label, x, margin.top + height + 20);
      });
    }

    // Y轴刻度和标签
    const tickCount = 5;
    for (let i = 0; i <= tickCount; i++) {
      const y = margin.top + (height / tickCount) * i;
      const value = Math.round((height - (y - margin.top)) / height * 100) / 100 * 200;

      // 刻度线
      ctx.beginPath();
      ctx.setStrokeStyle('#ccc');
      ctx.moveTo(margin.left - 5, y);
      ctx.lineTo(margin.left, y);
      ctx.stroke();

      // 标签
      ctx.setFillStyle('#666');
      ctx.setFontSize(12);
      ctx.setTextAlign('right');
      ctx.fillText(value, margin.left - 10, y + 5);
    }
  }

  // 绘制网格线
  function drawGridLines(ctx, margin, width, height, xCount, yCount) {
    ctx.setStrokeStyle('#eee');
    ctx.setLineWidth(1);

    // 水平线
    for (let i = 1; i < yCount; i++) {
      const y = margin.top + (height / yCount) * i;
      ctx.beginPath();
      ctx.moveTo(margin.left, y);
      ctx.lineTo(margin.left + width, y);
      ctx.stroke();
    }

    // 垂直线
    for (let i = 1; i < xCount - 1; i++) {
      const x = margin.left + (width / (xCount - 1)) * i;
      ctx.beginPath();
      ctx.moveTo(x, margin.top);
      ctx.lineTo(x, margin.top + height);
      ctx.stroke();
    }
  }

  // 绘制折线系列
  function drawLineSeries(ctx, margin, dataset, xScale, yScale, chartHeight) {
    // 绘制线条
    ctx.beginPath();
    ctx.setStrokeStyle(dataset.color);
    ctx.setLineWidth(2);

    dataset.data.forEach((value, index) => {
      const x = margin.left + index * xScale;
      const y = margin.top + chartHeight - value * yScale;

      if (index === 0) {
        ctx.moveTo(x, y);
      } else {
        ctx.lineTo(x, y);
      }

      // 绘制数据点
      ctx.beginPath();
      ctx.arc(x, y, 4, 0, Math.PI * 2);
      ctx.setFillStyle(dataset.color);
      ctx.fill();
      ctx.setStrokeStyle('#fff');
      ctx.setLineWidth(1);
      ctx.stroke();
    });

    ctx.stroke();
  }

  // 绘制图例
  function drawLegend(ctx, margin, datasets, width) {
    datasets.forEach((dataset, index) => {
      const x = width - margin.right - 150;
      const y = margin.top + 10 + index * 25;

      // 图例颜色块
      ctx.setFillStyle(dataset.color);
      ctx.fillRect(x, y, 15, 15);

      // 图例文本
      ctx.setFillStyle('#333');
      ctx.setFontSize(14);
      ctx.fillText(dataset.label, x + 25, y + 12);
    });
  }

  onMounted(() => {
    console.log('自定义图表页面加载完成');
  });
</script>

<style scoped>
  .container {
    padding: 16px;
    background-color: #f5f5f5;
    min-height: 100vh;
  }

  .page-title {
    font-size: 24px;
    font-weight: bold;
    text-align: center;
    margin: 20px 0 30px;
    color: #333;
  }

  .chart-card {
    background-color: #fff;
    border-radius: 10px;
    padding: 16px;
    margin-bottom: 20px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }

  .chart-title {
    font-size: 18px;
    margin-bottom: 12px;
    color: #555;
    font-weight: 500;
  }

  .chart-canvas {
    width: 100%;
    height: 300px;
  }
</style>